package gizwits.kit.byteutil;

import java.lang.reflect.Array;
import java.security.MessageDigest;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.ArrayUtils;

public class ByteUtil {
	public static byte[] convert(byte[] b) {
		byte[] cmdCode = ByteUtil.reverse(new byte[]{(byte)0x90, 0x05});
		byte[] pid = ByteUtil.arrayCopy(b, 4, 4);//包序号
		byte[] timestamp = ByteUtil.reverse(ByteUtil.getTimeStamp());//时间戳
		byte[] result = ByteUtil.arrayAddAll(cmdCode, pid, timestamp);
		result = ByteUtil.addLength(result);
		return result;
	}
	
	public static String printHexString(byte[] message){
		return printHexString("", message);
	}
	
	public static String printHexString(byte b){
		 return Integer.toHexString(b & 0xFF);
	}
	
	public static String printHexString(String msg, byte[] b)
    {    
		StringBuilder sb = new StringBuilder();
        for (int i = 0; i < b.length; i++)    
        {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1)
            {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        } 
        return sb.toString();
    }
	
	/**
	 * 在byte数组前面添加2bytes，其值为新的byte的长度
	 * @param source
	 * @return
	 */
	public static byte[] addLength(byte[] source) {
		byte[] length = intToBytes(source.length + 2);
		byte[] result = new byte[source.length + 2];
		System.arraycopy(source, 0, result, 2, source.length);
		System.arraycopy(length, 0, result, 0, 2);
		source = result;
		return result;
	}
	
	/**
	 * 获取byte[] 的长度
	 * @param source
	 * @return
	 */
	public static int getLength(byte[] source){
		byte[] length = new byte[2];
		System.arraycopy(source, 0, length, 0, 2);
		length = reverse(length);
		return ((length[0] << 8) & 0x0000ff00) | (length[1] & 0x000000ff);
	}
	
	public static byte[] intToBytes(int value)   
	{   
	    byte[] src = new byte[2];  
	    src[1] =  (byte) ((value>>8) & 0xFF);    
	    src[0] =  (byte) (value & 0xFF);                  
	    return src;   
	}  
	
	public static void main(String[] args){
		printHexString(arrayCopy(genSigned(getTimeStamp()), 0, 4));
	}
	
	/**
	 * 获取两个byte的timestamp
	 * @return
	 */
	public static byte[] getTimeStamp(){
		long timeMillis = System.currentTimeMillis();
		long timeSeconds = TimeUnit.MILLISECONDS.toSeconds(timeMillis);
		return longToBytes(timeSeconds);
	}
	
	/***
	 * 将byte数组翻转
	 * @param validData
	 * @return
	 */
	public static byte[] reverse(byte[] validData){
		ArrayUtils.reverse(validData);
		return validData;
	}
	
	public static byte[] longToBytes(long l) {  
		byte[] b = new byte[4];  
		b[0] = (byte) (l >>> 24);  
		b[1] = (byte) (l >>> 16);  
		b[2] = (byte) (l >>> 8);  
		b[3] = (byte) (l);  
		return b;  
	} 
	
	public static long bytesToLong(byte[] b) {  
		long temp = 0;  
	    long res = 0;  
	    for (int i=0;i<8;i++) {  
	        res <<= 8;  
	        temp = b[i] & 0xff;  
	        res |= temp;  
	    }  
	    return res; 
    } 
	
	/**
	 * byte数组深复制
	 * @param source source
	 * @param start source 的开始，从0开始算
	 * @param length 截取source的长度
	 * @return
	 */
	public static byte[] arrayCopy(byte[] source, int start, int length){
		byte[] result = new byte[length];
		printHexString(source);
		System.arraycopy(source, start, result, 0, length);
		printHexString(result);
		return result;
	}
	
	/***
	 * 组合byte数组
	 * @param src src
	 * @param bs byte array array
	 * @return
	 */
	public static byte[] arrayAddAll(byte[]... bs){
		byte[] result = bs[0];
		for(int i=1;i<bs.length;i++){
			result = ArrayUtils.addAll(result, bs[i]);
		}
		return result;
	}
	
	/**
	 * 根据source生产签名
	 * @param source
	 * @return
	 */
	public static byte[] genSigned(byte[] source){
		byte[] dsecret = new byte[16];
		try{
			dsecret = MessageDigest.getInstance("MD5").digest(source);
		}catch(Exception e){
			e.printStackTrace();
		}
		return dsecret;
	}
	
	/**
	 * 字符串ip转byte[]
	 * @param ip
	 * @return
	 */
	public static byte[] getIp(String ip){
		byte[] data = new byte[4];
		String[] strs = ip.split("\\.");
		for (int i = 0; i < strs.length; i++) {
			data[i] = (byte) Integer.parseInt(strs[i]);
		}
		return data;
	}
	
	/**
	 * byte[] 的ip转 xx.xx.xx.xx
	 * @param ip
	 * @return
	 */
	public static String getIp(byte[] ip){
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<ip.length;i++){
			int t = 0x00 << 24 | ip[i] & 0xff;
			sb.append(String.valueOf(t));
			if(i < ip.length-1){
				sb.append(".");
			}
		}
		return sb.toString();
	}
	
	public static String getPort(byte[] port){
		return String.valueOf((int) ((port[0] & 0xFF)
	            | ((port[1] & 0xFF)<<8))); 
	}
	
	public static byte[] getPort(int portNum){
		byte[] data = new byte[2];
		data[0] = (byte) (portNum / 256);
		data[1] = (byte) (portNum % 256);
		return data;
	}
	
	public static byte[] getPort(String port){
		byte[] data = new byte[2];
		int portNum = Integer.parseInt(port);
		data[0] = (byte) (portNum / 256);
		data[1] = (byte) (portNum % 256);
		return data;
	}
	
	/** 
     * 反转数组 
     *  
     */  
    @SuppressWarnings("unchecked")
	public static <T> T invertArray(T array) {  
        int len = Array.getLength(array);  
  
        Class<?> classz = array.getClass().getComponentType();  
  
        Object dest = Array.newInstance(classz, len);  
  
        System.arraycopy(array, 0, dest, 0, len);  
  
        Object temp;  
  
        for (int i = 0; i < (len / 2); i++) {  
            temp = Array.get(dest, i);  
            Array.set(dest, i, Array.get(dest, len - i - 1));  
            Array.set(dest, len - i - 1, temp);  
        }  
        return (T)dest;  
    } 
    
    /* Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。  
    * @param src byte[] data  
    * @return hex string  
    */     
   public static String bytesToHexString(byte[] src){
       StringBuilder stringBuilder = new StringBuilder("");  
       if (src == null || src.length <= 0) {  
           return null;  
       }  
       for (int i = 0; i < src.length; i++) {  
           int v = src[i] & 0xFF;  
           String hv = Integer.toHexString(v);
           if (hv.length() < 2) {  
               stringBuilder.append(0);  
           }  
           stringBuilder.append(hv);  
       }  
       return stringBuilder.toString();  
   }  
   /** 
    * Convert hex string to byte[] 
    * @param hexString the hex string 
    * @return byte[] 
    */  
   public static byte[] hexStringToBytes(String hexString) {
       if (hexString == null || hexString.equals("")) {  
           return null;  
       }  
       hexString = hexString.toUpperCase();  
       int length = hexString.length() / 2;  
       char[] hexChars = hexString.toCharArray();  
       byte[] d = new byte[length];  
       for (int i = 0; i < length; i++) {  
           int pos = i * 2;  
           d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
       }  
       return d;  
   }  
   /** 
    * Convert char to byte 
    * @param c char 
    * @return byte 
    */  
    private static byte charToByte(char c) {  
       return (byte) "0123456789ABCDEF".indexOf(c);  
   } 
    
    /**
     * 拆分MD5签名16字节再相加
     * @param sign
     * @return
     */
    public static long getSignData(byte[] sign){
    	long sign1 = ByteKit.toLong(ByteUtil.arrayCopy(sign, 0, 4),false);
		long sign2 = ByteKit.toLong(ByteUtil.arrayCopy(sign, 4, 4),false);
		long sign3 = ByteKit.toLong(ByteUtil.arrayCopy(sign, 8, 4),false);
		long sign4 = ByteKit.toLong(ByteUtil.arrayCopy(sign, 12, 4),false);
		return sign1+sign2+sign3+sign4;
    }
}
